home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / bash_114.zip / bash-1.14.2 / variables.c < prev    next >
C/C++ Source or Header  |  1994-07-14  |  45KB  |  1,805 lines

  1. /* variables.c -- Functions for hacking shell variables. */
  2.  
  3. /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
  4.  
  5.    This file is part of GNU Bash, the Bourne Again SHell.
  6.  
  7.    Bash is free software; you can redistribute it and/or modify it
  8.    under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 1, or (at your option)
  10.    any later version.
  11.  
  12.    Bash is distributed in the hope that it will be useful, but WITHOUT
  13.    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14.    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  15.    License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with Bash; see the file COPYING.  If not, write to the Free
  19.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include <stdio.h>
  22. #include "bashtypes.h"
  23. #include "posixstat.h"
  24. #include <ctype.h>
  25. #include <pwd.h>
  26.  
  27. #include "bashansi.h"
  28. #include "shell.h"
  29. #include "hash.h"
  30. #include "flags.h"
  31. #include "execute_cmd.h"
  32.  
  33. #include "builtins/common.h"
  34. #include <tilde/tilde.h>
  35.  
  36. /* Variables used here and defined in other files. */
  37. extern int posixly_correct;
  38. extern int variable_context, line_number;
  39. extern int interactive, interactive_shell, login_shell, shell_level;
  40. extern int subshell_environment;
  41. extern int build_version;
  42. extern char *dist_version;
  43. extern char *shell_name;
  44. extern char *primary_prompt, *secondary_prompt;
  45. extern Function *this_shell_builtin;
  46. extern time_t shell_start_time;
  47.  
  48. /* The list of shell variables that the user has created, or that came from
  49.    the environment. */
  50. HASH_TABLE *shell_variables = (HASH_TABLE *)NULL;
  51.  
  52. /* The list of shell functions that the user has created, or that came from
  53.    the environment. */
  54. HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
  55.  
  56. /* The current variable context.  This is really a count of how deep into
  57.    executing functions we are. */
  58. int variable_context = 0;
  59.  
  60. /* The array of shell assignments which are made only in the environment
  61.    for a single command. */
  62. char **temporary_env = (char **)NULL;
  63.  
  64. /* The array of shell assignments which are in the environment for the
  65.    execution of a shell function. */
  66. char **function_env = (char **)NULL;
  67.  
  68. /* The array of shell assignments which are made only in the environment
  69.    for the execution of a shell builtin command which may cause more than
  70.    one command to be executed (e.g., "source"). */
  71. char **builtin_env = (char **)NULL;
  72.  
  73. /* Some funky variables which are known about specially.  Here is where
  74.    "$*", "$1", and all the cruft is kept. */
  75. char *dollar_vars[10];
  76. WORD_LIST *rest_of_args = (WORD_LIST *)NULL;
  77.  
  78. /* The value of $$. */
  79. int dollar_dollar_pid;
  80.  
  81. /* An array which is passed to commands as their environment.  It is
  82.    manufactured from the overlap of the initial environment and the
  83.    shell variables that are marked for export. */
  84. char **export_env = (char **)NULL;
  85.  
  86. /* Non-zero means that we have to remake EXPORT_ENV. */
  87. int array_needs_making = 1;
  88.  
  89. /* The list of variables that may not be unset in this shell. */
  90. char **non_unsettable_vars = (char **)NULL;
  91.  
  92. #if defined (USG)
  93. #define DEFAULT_MAIL_PATH "/usr/mail/"
  94. #else
  95. #define DEFAULT_MAIL_PATH "/usr/spool/mail/"
  96. #endif
  97.  
  98. static char *have_local_variables;        /* XXX */
  99. static int local_variable_stack_size = 0;    /* XXX */
  100.  
  101. /* Some forward declarations. */
  102. static void initialize_dynamic_variables ();
  103. static void sbrand ();        /* set bash random number generator. */
  104. static int qsort_var_comp ();
  105.  
  106. /* Make VAR be auto-exported.  VAR is a pointer to a SHELL_VAR. */
  107. #define set_auto_export(var) \
  108. { var->attributes |= att_exported; array_needs_making = 1; }
  109.  
  110. #if defined (HISTORY)
  111. #  include "bashhist.h"
  112. #endif /* HISTORY */
  113.  
  114. /* Initialize the shell variables from the current environment. */
  115. void
  116. initialize_shell_variables (env)
  117.      char **env;
  118. {
  119.   char *name, *string, *current_dir;
  120.   int c, char_index;
  121.   int string_index = 0;
  122.   SHELL_VAR *temp_var;
  123.  
  124.   if (!shell_variables)
  125.     shell_variables = make_hash_table (0);
  126.  
  127.   if (!shell_functions)
  128.     shell_functions = make_hash_table (0);
  129.  
  130.   while (string = env[string_index++])
  131.     {
  132.       int string_length;
  133.  
  134.       char_index = 0;
  135.  
  136.       string_length = strlen (string);
  137.       name = xmalloc (1 + string_length);
  138.  
  139.       while ((c = *string++) && c != '=')
  140.     name[char_index++] = c;
  141.  
  142.       name[char_index] = '\0';
  143.  
  144.       /* If exported function, define it now. */
  145.       if (!privileged_mode && STREQN ("() {", string, 4))
  146.     {
  147.       SHELL_VAR *f;
  148.       char *eval_string;
  149.  
  150.       eval_string = xmalloc (3 + string_length + strlen (name));
  151.       sprintf (eval_string, "%s %s", name, string);
  152.  
  153.       parse_and_execute (eval_string, name, 0);
  154.  
  155.       if (name[char_index - 1] == ')')
  156.         name[char_index - 2] = '\0';
  157.  
  158.       if (f = find_function (name))
  159.         {
  160.           f->attributes |= (att_exported | att_imported);
  161.           array_needs_making = 1;
  162.         }
  163.       else
  164.         report_error ("error importing function definition for `%s'", name);
  165.     }
  166.       else
  167.     {
  168.       SHELL_VAR *v;
  169.  
  170.       v = bind_variable (name, string);
  171.       v->attributes |= (att_exported | att_imported);
  172.       array_needs_making = 1;
  173.     }
  174.       free (name);
  175.     }
  176.  
  177.   /* If we got PWD from the environment, update our idea of the current
  178.      working directory.  In any case, make sure that PWD exists before
  179.      checking it.  It is possible for getwd () to fail on shell startup,
  180.      and in that case, PWD would be undefined. */
  181.   temp_var = find_variable ("PWD");
  182.   if (temp_var && imported_p (temp_var) &&
  183.       (current_dir = value_cell (temp_var)) &&
  184.       same_file (current_dir, ".", (struct stat *)NULL, (struct stat *)NULL))
  185.     set_working_directory (current_dir);
  186.   else
  187.     {
  188.       current_dir = get_working_directory ("shell-init");
  189.       if (current_dir)
  190.         {
  191.       bind_variable ("PWD", current_dir);
  192.       free (current_dir);
  193.         }
  194.     }
  195.  
  196.   /* Remember this pid. */
  197.   dollar_dollar_pid = (int)getpid ();
  198.  
  199.   /* Now make our own defaults in case the vars that we think are
  200.      important are missing. */
  201.   temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE);
  202.   set_auto_export (temp_var);
  203.  
  204.   temp_var = set_if_not ("TERM", "dumb");
  205.   set_auto_export (temp_var);
  206.  
  207.   if (interactive_shell)
  208.     {
  209.       set_if_not ("PS1", primary_prompt);
  210.       set_if_not ("PS2", secondary_prompt);
  211.     }
  212.  
  213. #if defined (INSECURITY)
  214.   set_if_not ("IFS", " \t\n");
  215. #else
  216.   bind_variable ("IFS", " \t\n");
  217. #endif /* INSECURITY */
  218.  
  219.   /* Magic machine types.  Pretty convenient. */
  220.   temp_var = set_if_not ("HOSTTYPE", HOSTTYPE);
  221.   set_auto_export (temp_var);
  222.   temp_var = set_if_not ("OSTYPE", OSTYPE);
  223.   set_auto_export (temp_var);
  224.  
  225.   /* Default MAILPATH, and MAILCHECK for interactive shells. */
  226.   if (interactive_shell)
  227.     {
  228.       set_if_not ("MAILCHECK", "60");
  229.  
  230.       if ((get_string_value ("MAIL") == (char *)NULL) &&
  231.       (get_string_value ("MAILPATH") == (char *)NULL))
  232.     {
  233.       char *tem;
  234.  
  235.       tem = xmalloc (1 + sizeof (DEFAULT_MAIL_PATH)
  236.                + strlen (current_user.user_name));
  237.       strcpy (tem, DEFAULT_MAIL_PATH);
  238.       strcat (tem, current_user.user_name);
  239.  
  240.       bind_variable ("MAILPATH", tem);
  241.       free (tem);
  242.     }
  243.     }
  244.  
  245.   /* Do some things with shell level. */
  246.   temp_var = set_if_not ("SHLVL", "0");
  247.   set_auto_export (temp_var);
  248.   adjust_shell_level (1);
  249.  
  250.   /* Make a variable $PPID, which holds the pid of the shell's parent.  */
  251.   {
  252.     char *ppid;
  253.     SHELL_VAR *v;
  254.  
  255.     ppid = itos ((int) getppid ());
  256.     v = find_variable ("PPID");
  257.  
  258.     if (v)
  259.       v->attributes &= ~(att_readonly | att_exported);
  260.  
  261.     v = bind_variable ("PPID", ppid);
  262.     v->attributes |= (att_readonly | att_integer);
  263.  
  264.     non_unsettable ("PPID");
  265.     free (ppid);
  266.   }
  267.  
  268. #if defined (GETOPTS_BUILTIN)
  269.   /* Initialize the `getopts' stuff. */
  270.   bind_variable ("OPTIND", "1");
  271.   bind_variable ("OPTERR", "1");
  272. #endif /* GETOPTS_BUILTIN */
  273.  
  274.   /* Get the full pathname to THIS shell, and set the BASH variable
  275.      to it. */
  276.   {
  277.     char *tname = find_user_command (shell_name);
  278.  
  279.     if ((login_shell == 1) && (*shell_name != '/'))
  280.       {
  281.     /* If HOME doesn't exist, set it. */
  282.     temp_var = set_if_not ("HOME", current_user.home_dir);
  283.     temp_var->attributes |= att_exported;
  284.  
  285.     name = savestring (current_user.shell);
  286.       }
  287.     else
  288.       {
  289.     if (!tname)
  290.       name = make_absolute (shell_name, get_string_value ("PWD"));
  291.     else
  292.       {
  293.         name = full_pathname (tname);
  294.         free (tname);
  295.       }
  296.       }
  297.  
  298.     /* Make the exported environment variable SHELL be the user's login
  299.        shell.  Note that the `tset' command looks at this variable
  300.        to determine what style of commands to output; if it ends in "csh",
  301.        then C-shell commands are output, else Bourne shell commands. */
  302.     temp_var = set_if_not ("SHELL", current_user.shell);
  303.     set_auto_export (temp_var);
  304.  
  305.     /* Make a variable called BASH, which is the name of THIS shell. */
  306.     temp_var = bind_variable ("BASH", name);
  307.     temp_var->attributes |= att_exported;
  308.  
  309.     free (name);
  310.   }
  311.  
  312.   /* Make a variable called BASH_VERSION which contains the version info. */
  313.   bind_variable ("BASH_VERSION", shell_version_string ());
  314.  
  315.   /* Find out if we're supposed to be in Posix.2 mode via an
  316.      environment variable. */
  317.   temp_var = find_variable ("POSIXLY_CORRECT");
  318.   if (!temp_var)
  319.     temp_var = find_variable ("POSIX_PEDANTIC");
  320.   if (temp_var && imported_p (temp_var))
  321.     sv_strict_posix (temp_var->name);
  322.  
  323. #if defined (HISTORY)
  324.   /* Set history variables to defaults, and then do whatever we would
  325.      do if the variable had just been set.  Do this only in the case
  326.      that we are remembering commands on the history list. */
  327.   if (remember_on_history)
  328.     {
  329.       if (posixly_correct)
  330.     name = tilde_expand ("~/.sh_history");
  331.       else
  332.     name = tilde_expand ("~/.bash_history");
  333.  
  334.       set_if_not ("HISTFILE", name);
  335.       free (name);
  336.  
  337.       set_if_not ("HISTSIZE", "500");
  338.       sv_histsize ("HISTSIZE");
  339.     }
  340. #endif /* HISTORY */
  341.  
  342.   /* Seed the random number generator. */
  343.   sbrand (dollar_dollar_pid);
  344.  
  345.   /* Handle some "special" variables that we may have inherited from a
  346.      parent shell. */
  347.  
  348.   noclobber = find_variable ("noclobber") != (SHELL_VAR *)NULL;
  349.  
  350.   temp_var = find_variable ("IGNOREEOF");
  351.   if (!temp_var)
  352.     temp_var = find_variable ("ignoreeof");
  353.   if (temp_var && imported_p (temp_var))
  354.     sv_ignoreeof (temp_var->name);
  355.  
  356. #if defined (HISTORY)
  357.   if (interactive_shell && remember_on_history)
  358.     {
  359.       sv_command_oriented_history ("command_oriented_history");
  360.       if (find_variable ("history_control"))
  361.     sv_history_control ("history_control");    /* gone in next release */
  362.       else
  363.     sv_history_control ("HISTCONTROL");
  364.     }
  365. #endif /* HISTORY */
  366.  
  367.   /* Initialize the dynamic variables, and seed their values. */
  368.   initialize_dynamic_variables ();
  369.  
  370.   non_unsettable ("PATH");
  371.   non_unsettable ("IFS");
  372.  
  373.   if (interactive_shell)
  374.     {
  375.       non_unsettable ("PS1");
  376.       non_unsettable ("PS2");
  377.     }
  378.  
  379.   /* Get the users real user id, and save that in a readonly variable.
  380.      To make the variable *really* readonly, we have added it to a special
  381.      list of vars. */
  382.  
  383.   sv_uids ();
  384.   set_var_read_only ("UID");
  385.   set_var_read_only ("EUID");
  386.  
  387.   non_unsettable ("EUID");
  388.   non_unsettable ("UID");
  389. }
  390.  
  391. void
  392. adjust_shell_level (change)
  393.      int change;
  394. {
  395.   char *new_level, *old_SHLVL;
  396.   int old_level;
  397.  
  398.   old_SHLVL = get_string_value ("SHLVL");
  399.   if (old_SHLVL)
  400.     old_level = atoi (old_SHLVL);
  401.   else
  402.     old_level = 0;
  403.  
  404.   shell_level = old_level + change;
  405.   if (shell_level < 0)
  406.     shell_level = 0;
  407.   new_level = itos (shell_level);
  408.   bind_variable ("SHLVL", new_level);
  409.   free (new_level);
  410. }
  411.  
  412. /* Add NAME to the list of variables that cannot be unset
  413.    if it isn't already there. */
  414. void
  415. non_unsettable (name)
  416.      char *name;
  417. {
  418.   register int i;
  419.  
  420.   if (!non_unsettable_vars)
  421.     {
  422.       non_unsettable_vars = (char **)xmalloc (1 * sizeof (char *));
  423.       non_unsettable_vars[0] = (char *)NULL;
  424.     }
  425.  
  426.   for (i = 0; non_unsettable_vars[i]; i++)
  427.     if (STREQ (non_unsettable_vars[i], name))
  428.       return;
  429.  
  430.   non_unsettable_vars = (char **)
  431.     xrealloc (non_unsettable_vars, (2 + i) * sizeof (char *));
  432.   non_unsettable_vars[i] = savestring (name);
  433.   non_unsettable_vars[i + 1] = (char *)NULL;
  434. }
  435.  
  436. /* Set NAME to VALUE if NAME has no value. */
  437. SHELL_VAR *
  438. set_if_not (name, value)
  439.      char *name, *value;
  440. {
  441.   SHELL_VAR *v = find_variable (name);
  442.  
  443.   if (!v)
  444.     v = bind_variable (name, value);
  445.   return (v);
  446. }
  447.  
  448. /* Map FUNCTION over the variables in VARIABLES.  Return an array of the
  449.    variables that satisfy FUNCTION.  Satisfy means that FUNCTION returns
  450.    a non-zero value for.  A NULL value for FUNCTION means to use all
  451.    variables. */
  452. SHELL_VAR **
  453. map_over (function, var_hash_table)
  454.      Function *function;
  455.      HASH_TABLE* var_hash_table;
  456. {
  457.   register int i;
  458.   register BUCKET_CONTENTS *tlist;
  459.   SHELL_VAR *var, **list = (SHELL_VAR **)NULL;
  460.   int list_index = 0, list_size = 0;
  461.  
  462.   for (i = 0; i < var_hash_table->nbuckets; i++)
  463.     {
  464.       tlist = get_hash_bucket (i, var_hash_table);
  465.  
  466.       while (tlist)
  467.     {
  468.       var = (SHELL_VAR *)tlist->data;
  469.  
  470.       if (!function || (*function) (var))
  471.         {
  472.           if (list_index + 1 >= list_size)
  473.         list = (SHELL_VAR **)
  474.           xrealloc (list, (list_size += 20) * sizeof (SHELL_VAR *));
  475.  
  476.           list[list_index++] = var;
  477.           list[list_index] = (SHELL_VAR *)NULL;
  478.         }
  479.       tlist = tlist->next;
  480.     }
  481.     }
  482.   return (list);
  483. }
  484.  
  485. void
  486. sort_variables (array)
  487.      SHELL_VAR **array;
  488. {
  489.   qsort (array, array_len ((char **)array), sizeof (SHELL_VAR *), qsort_var_comp);
  490. }
  491.  
  492. static int
  493. qsort_var_comp (var1, var2)
  494.      SHELL_VAR **var1, **var2;
  495. {
  496.   int result;
  497.  
  498.   if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0)
  499.     result = strcmp ((*var1)->name, (*var2)->name);
  500.  
  501.   return (result);
  502. }
  503.  
  504. /* Create a NULL terminated array of all the shell variables in TABLE. */
  505. static SHELL_VAR **
  506. all_vars (table)
  507.      HASH_TABLE *table;
  508. {
  509.   SHELL_VAR **list;
  510.  
  511.   list = map_over ((Function *)NULL, table);
  512.   if (list)
  513.     sort_variables (list);
  514.   return (list);
  515. }
  516.  
  517. /* Create a NULL terminated array of all the shell variables. */
  518. SHELL_VAR **
  519. all_shell_variables ()
  520. {
  521.   return (all_vars (shell_variables));
  522. }
  523.  
  524. /* Create a NULL terminated array of all the shell functions. */
  525. SHELL_VAR **
  526. all_shell_functions ()
  527. {
  528.   return (all_vars (shell_functions));
  529. }
  530.  
  531. /* Print VARS to stdout in such a way that they can be read back in. */
  532. void
  533. print_var_list (list)
  534.      register SHELL_VAR **list;
  535. {
  536.   register int i;
  537.   register SHELL_VAR *var;
  538.  
  539.   for (i = 0; list && (var = list[i]); i++)
  540.     if (!invisible_p (var))
  541.       print_assignment (var);
  542. }
  543.  
  544. #if defined (NOTDEF)
  545. /* Print LIST (a linked list of shell variables) to stdout
  546.    by printing the names, without the values.  Used to support the
  547.    `set +' command. */
  548. print_vars_no_values (list)
  549.      register SHELL_VAR **list;
  550. {
  551.   register int i;
  552.   register SHELL_VAR *var;
  553.  
  554.   for (i = 0; list && (var = list[i]); i++)
  555.     if (!invisible_p (var))
  556.       printf ("%s\n", var->name);
  557. }
  558. #endif
  559.  
  560. /* Print the value of a single SHELL_VAR.  No newline is
  561.    output, but the variable is printed in such a way that
  562.    it can be read back in. */
  563. void
  564. print_assignment (var)
  565.      SHELL_VAR *var;
  566. {
  567.   if (function_p (var) && var->value)
  568.     {
  569.       printf ("%s=", var->name);
  570.       print_var_function (var);
  571.       printf ("\n");
  572.     }
  573.   else if (var->value)
  574.     {
  575.       printf ("%s=", var->name);
  576.       print_var_value (var);
  577.       printf ("\n");
  578.     }
  579. }
  580.  
  581. /* Print the value cell of VAR, a shell variable.  Do not print
  582.    the name, nor leading/trailing newline. */
  583. void
  584. print_var_value (var)
  585.      SHELL_VAR *var;
  586. {
  587.   if (var->value)
  588.     printf ("%s", var->value);
  589. }
  590.  
  591. /* Print the function cell of VAR, a shell variable.  Do not
  592.    print the name, nor leading/trailing newline. */
  593. void
  594. print_var_function (var)
  595.      SHELL_VAR *var;
  596. {
  597.   if (function_p (var) && var->value)
  598.     printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
  599. }
  600.  
  601. /* **************************************************************** */
  602. /*                                                                  */
  603. /*                 Dynamic Variable Extension                       */
  604. /*                                                                  */
  605. /* **************************************************************** */
  606.  
  607. /* DYNAMIC VARIABLES
  608.    
  609.    These are variables whose values are generated anew each time they are
  610.    referenced.  These are implemented using a pair of function pointers
  611.    in the struct variable: assign_func, which is called from bind_variable,
  612.    and dynamic_value, which is called from find_variable.
  613.    
  614.    assign_func is called from bind_variable, if bind_variable discovers
  615.    that the variable being assigned to has such a function.  The function
  616.    is called as
  617.       SHELL_VAR *temp = (*(entry->assign_func)) (entry, value)
  618.    and the (SHELL_VAR *)temp is returned as the value of bind_variable.  It
  619.    is usually ENTRY (self).
  620.    
  621.    dynamic_value is called from find_variable to return a `new' value for
  622.    the specified dynamic varible.  If this function is NULL, the variable
  623.    is treated as a `normal' shell variable.  If it is not, however, then
  624.    this function is called like this:
  625.       tempvar = (*(var->dynamic_value)) (var);
  626.    
  627.    Sometimes `tempvar' will replace the value of `var'.  Other times, the
  628.    shell will simply use the string value.  Pretty object-oriented, huh?
  629.    
  630.    Be warned, though: if you `unset' a special variable, it loses its
  631.    special meaning, even if you subsequently set it.
  632.    
  633.    The special assignment code would probably have been better put in
  634.    subst.c: do_assignment, in the same style as
  635.    stupidly_hack_special_variables, but I wanted the changes as
  636.    localized as possible.  */
  637.  
  638. /* The value of $SECONDS.  This is the number of seconds since shell
  639.    invocation, or, the number of seconds since the last assignment + the
  640.    value of the last assignment. */
  641. static long seconds_value_assigned = (long)0;
  642.  
  643. static SHELL_VAR *
  644. assign_seconds (self, value)
  645.      SHELL_VAR *self;
  646.      char *value;
  647. {
  648.   seconds_value_assigned = atol (value);
  649.   shell_start_time = NOW;
  650.   return (self);
  651. }
  652.  
  653. static SHELL_VAR *
  654. get_seconds (var)
  655.      SHELL_VAR *var;
  656. {
  657.   time_t time_since_start;
  658.   char *p;
  659.  
  660.   time_since_start = NOW - shell_start_time;
  661.   p = itos((int) seconds_value_assigned + time_since_start);
  662.  
  663.   FREE (var->value);
  664.  
  665.   var->attributes |= att_integer;
  666.   var->value = p;
  667.   return (var);
  668. }
  669.  
  670. /* The random number seed.  You can change this by setting RANDOM. */
  671. static unsigned long rseed = 1;
  672.  
  673. /* A linear congruential random number generator based on the ANSI
  674.    C standard.  A more complicated one is overkill.  */
  675.  
  676. /* Returns a pseudo-random number between 0 and 32767. */
  677. static int
  678. brand ()
  679. {
  680.   rseed = rseed * 1103515245 + 12345;
  681.   return ((unsigned int)(rseed / 65536) % 32768);
  682. }
  683.  
  684. /* Set the random number generator seed to SEED. */
  685. static void
  686. sbrand (seed)
  687.      int seed;
  688. {
  689.   rseed = seed;
  690. }
  691.  
  692. static SHELL_VAR *
  693. assign_random (self, value)
  694.      SHELL_VAR *self;
  695.      char *value;
  696. {
  697.   int s = atoi (value);
  698.  
  699.   sbrand (s);
  700.   return (self);
  701. }
  702.  
  703. static SHELL_VAR *
  704. get_random (var)
  705.      SHELL_VAR *var;
  706. {
  707.   int rv;
  708.   char *p;
  709.  
  710.   rv = brand ();
  711.   p = itos ((int)rv);
  712.  
  713.   FREE (var->value);
  714.  
  715.   var->attributes |= att_integer;
  716.   var->value = p;
  717.   return (var);
  718. }
  719.  
  720. /* Function which returns the current line number. */
  721. static SHELL_VAR *
  722. get_lineno (var)
  723.      SHELL_VAR *var;
  724. {
  725.   char *p;
  726.  
  727.   p = itos (line_number);
  728.   FREE (var->value);
  729.   var->value = p;
  730.   return (var);
  731. }
  732.  
  733. #if defined (HISTORY)
  734. static SHELL_VAR *
  735. get_histcmd (var)
  736.      SHELL_VAR *var;
  737. {
  738.   char *p;
  739.  
  740.   p = itos (history_number ());
  741.   FREE (var->value);
  742.   var->value = p;
  743.   return (var);
  744. }
  745. #endif
  746.  
  747. static void
  748. initialize_dynamic_variables ()
  749. {
  750.   SHELL_VAR *v;
  751.  
  752.   v = bind_variable ("SECONDS", (char *)NULL);
  753.   v->dynamic_value = get_seconds;
  754.   v->assign_func = assign_seconds;
  755.  
  756.   v = bind_variable ("RANDOM", (char *)NULL);
  757.   v->dynamic_value = get_random;
  758.   v->assign_func = assign_random;
  759.  
  760.   v = bind_variable ("LINENO", (char *)NULL);
  761.   v->dynamic_value = get_lineno;
  762.   v->assign_func = (DYNAMIC_FUNC *)NULL;
  763.  
  764. #if defined (HISTORY)
  765.   v = bind_variable ("HISTCMD", (char *)NULL);
  766.   v->dynamic_value = get_histcmd;
  767.   v->assign_func = (DYNAMIC_FUNC *)NULL;
  768. #endif
  769. }
  770.  
  771. /* How to get a pointer to the shell variable or function named NAME.
  772.    HASHED_VARS is a pointer to the hash table containing the list
  773.    of interest (either variables or functions). */
  774. SHELL_VAR *
  775. var_lookup (name, hashed_vars)
  776.      char *name;
  777.      HASH_TABLE *hashed_vars;
  778. {
  779.   BUCKET_CONTENTS *bucket;
  780.  
  781.   bucket = find_hash_item (name, hashed_vars);
  782.  
  783.   if (bucket)
  784.     return ((SHELL_VAR *)bucket->data);
  785.   else
  786.     return ((SHELL_VAR *)NULL);
  787. }
  788.  
  789. /* Look up the variable entry named NAME.  If SEARCH_TEMPENV is non-zero,
  790.    then also search the temporarily built list of exported variables. */
  791. SHELL_VAR *
  792. find_variable_internal (name, search_tempenv)
  793.      char *name;
  794.      int search_tempenv;
  795. {
  796.   SHELL_VAR *var = (SHELL_VAR *)NULL;
  797.  
  798.   /* If explicitly requested, first look in the temporary environment for
  799.      the variable.  This allows constructs such as "foo=x eval 'echo $foo'"
  800.      to get the `exported' value of $foo.  This happens if we are executing
  801.      a function or builtin, or if we are looking up a variable in a
  802.      "subshell environment". */
  803.   if ((search_tempenv || subshell_environment) &&
  804.       (temporary_env || builtin_env || function_env))
  805.     var = find_tempenv_variable (name);
  806.  
  807.   if (!var)
  808.     var = var_lookup (name, shell_variables);
  809.  
  810.   if (!var)
  811.     return ((SHELL_VAR *)NULL);
  812.  
  813.   if (var->dynamic_value)
  814.     return ((*(var->dynamic_value)) (var));
  815.   else
  816.     return (var);
  817. }
  818.  
  819. /* Look up the variable entry named NAME.  Returns the entry or NULL. */
  820. SHELL_VAR *
  821. find_variable (name)
  822.      char *name;
  823. {
  824.   return (find_variable_internal
  825.       (name, (variable_context || this_shell_builtin || builtin_env)));
  826. }
  827.  
  828. /* Look up the function entry whose name matches STRING.
  829.    Returns the entry or NULL. */
  830. SHELL_VAR *
  831. find_function (name)
  832.      char *name;
  833. {
  834.   return (var_lookup (name, shell_functions));
  835. }
  836.  
  837. /* Return the string value of a variable.  Return NULL if the variable
  838.    doesn't exist, or only has a function as a value.  Don't cons a new
  839.    string. */
  840. char *
  841. get_string_value (var_name)
  842.      char *var_name;
  843. {
  844.   SHELL_VAR *var = find_variable (var_name);
  845.  
  846.   if (!var)
  847.     return (char *)NULL;
  848.   else
  849.     return (var->value);
  850. }
  851.  
  852. /* Create a local variable referenced by NAME. */
  853. SHELL_VAR *
  854. make_local_variable (name)
  855.      char *name;
  856. {
  857.   SHELL_VAR *new_var, *old_var;
  858.   BUCKET_CONTENTS *elt;
  859.  
  860.   /* local foo; local foo;  is a no-op. */
  861.   old_var = find_variable (name);
  862.   if (old_var && old_var->context == variable_context)
  863.     return (old_var);
  864.  
  865.   elt = remove_hash_item (name, shell_variables);
  866.   if (elt)
  867.     {
  868.       old_var = (SHELL_VAR *)elt->data;
  869.       free (elt->key);
  870.       free (elt);
  871.     }
  872.   else
  873.     old_var = (SHELL_VAR *)NULL;
  874.  
  875.   /* If a variable does not already exist with this name, then
  876.      just make a new one. */
  877.   if (!old_var)
  878.     {
  879.       new_var = bind_variable (name, "");
  880.     }
  881.   else
  882.     {
  883.       new_var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
  884.  
  885.       new_var->name = savestring (name);
  886.       new_var->value = savestring ("");
  887.  
  888.       new_var->dynamic_value = (DYNAMIC_FUNC *)NULL;
  889.       new_var->assign_func = (DYNAMIC_FUNC *)NULL;
  890.  
  891.       new_var->attributes = 0;
  892.  
  893.       if (exported_p (old_var))
  894.     new_var->attributes |= att_exported;
  895.  
  896.       new_var->prev_context = old_var;
  897.       elt = add_hash_item (savestring (name), shell_variables);
  898.       elt->data = (char *)new_var;
  899.     }
  900.  
  901.   new_var->context = variable_context;
  902.  
  903.   /* XXX */
  904.   if (local_variable_stack_size <= variable_context)
  905.     {
  906.       int old_size = local_variable_stack_size;
  907.       while (local_variable_stack_size <= variable_context)
  908.         local_variable_stack_size += 8;
  909.       have_local_variables =
  910.         xrealloc (have_local_variables, local_variable_stack_size);
  911.       bzero ((char *)have_local_variables + old_size,
  912.          local_variable_stack_size - old_size);
  913.     }
  914.   have_local_variables[variable_context] = 1;        /* XXX */
  915.  
  916.   return (new_var);
  917. }
  918.  
  919. /* Bind a variable NAME to VALUE.  This conses up the name
  920.    and value strings. */
  921. SHELL_VAR *
  922. bind_variable (name, value)
  923.      char *name, *value;
  924. {
  925.   SHELL_VAR *entry = var_lookup (name, shell_variables);
  926.   BUCKET_CONTENTS *elt;
  927.  
  928.   if (!entry)
  929.     {
  930.       /* Make a new entry for this variable.  Then do the binding. */
  931.       entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
  932.  
  933.       entry->attributes = 0;
  934.       entry->name = savestring (name);
  935.  
  936.       if (value)
  937.     {
  938.       if (*value)
  939.         entry->value = savestring (value);
  940.       else
  941.         {
  942.           entry->value = xmalloc (1);
  943.           entry->value[0] = '\0';
  944.         }
  945.     }
  946.       else
  947.     entry->value = (char *)NULL;
  948.  
  949.       entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
  950.       entry->assign_func = (DYNAMIC_FUNC *)NULL;
  951.  
  952.       /* Always assume variables are to be made at toplevel!
  953.      make_local_variable has the responsibilty of changing the
  954.      variable context. */
  955.       entry->context = 0;
  956.       entry->prev_context = (SHELL_VAR *)NULL;
  957.  
  958.       elt = add_hash_item (savestring (name), shell_variables);
  959.       elt->data = (char *)entry;
  960.     }
  961.   else if (entry->assign_func)
  962.     return ((*(entry->assign_func)) (entry, value));
  963.   else
  964.     {
  965.       if (readonly_p (entry))
  966.     {
  967.       report_error ("%s: read-only variable", name);
  968.       return (entry);
  969.     }
  970.  
  971.       /* Variables which are bound are visible. */
  972.       entry->attributes &= ~att_invisible;
  973.  
  974.       /* If this variable has had its type set to integer (via `declare -i'),
  975.      then do expression evaluation on it and store the result.  The
  976.      functions in expr.c (evalexp and bind_int_variable) are responsible
  977.      for turning off the integer flag if they don't want further
  978.      evaluation done. */
  979.       if (integer_p (entry))
  980.     {
  981.       long val;
  982.  
  983.       val = evalexp (value);
  984.       /* We cannot free () entry->value before this; what if the string
  985.          we are working is `even=even+2'?  We need the original value
  986.          around while we are doing the evaluation to handle any possible
  987.          recursion. */
  988.       FREE (entry->value);
  989.       entry->value = itos (val);
  990.     }
  991.       else
  992.     {
  993.       FREE (entry->value);
  994.  
  995.       if (value)
  996.         {
  997.           if (*value)
  998.         entry->value = savestring (value);
  999.           else
  1000.         {
  1001.           entry->value = xmalloc (1);
  1002.           entry->value[0] = '\0';
  1003.         }
  1004.         }
  1005.       else
  1006.         entry->value = (char *)NULL;
  1007.     }
  1008.     }
  1009.  
  1010.   if (mark_modified_vars)
  1011.     entry->attributes |= att_exported;
  1012.  
  1013.   if (exported_p (entry))
  1014.     array_needs_making = 1;
  1015.  
  1016.   return (entry);
  1017. }
  1018.  
  1019. /* Dispose of the information attached to VAR. */
  1020. void
  1021. dispose_variable (var)
  1022.      SHELL_VAR *var;
  1023. {
  1024.   if (!var)
  1025.     return;
  1026.  
  1027.   if (function_p (var))
  1028.     dispose_command ((COMMAND *)var->value);
  1029.   else if (var->value)
  1030.     free (var->value);
  1031.  
  1032.   free (var->name);
  1033.  
  1034.   if (exported_p (var))
  1035.     array_needs_making = 1;
  1036.  
  1037.   free (var);
  1038. }
  1039.  
  1040. /* Unset the variable referenced by NAME. */
  1041. unbind_variable (name)
  1042.      char *name;
  1043. {
  1044.   SHELL_VAR *var = find_variable (name);
  1045.  
  1046.   if (!var)
  1047.     return (-1);
  1048.  
  1049.   if (var->value)
  1050.     {
  1051.       free (var->value);
  1052.       var->value = (char *)NULL;
  1053.     }
  1054.  
  1055.   makunbound (name, shell_variables);
  1056.  
  1057.   return (0);
  1058. }
  1059.  
  1060. /* Make the variable associated with NAME go away.  HASH_LIST is the
  1061.    hash table from which this variable should be deleted (either
  1062.    shell_variables or shell_functions).
  1063.    Returns non-zero if the variable couldn't be found. */
  1064. makunbound (name, hash_list)
  1065.      char *name;
  1066.      HASH_TABLE *hash_list;
  1067. {
  1068.   BUCKET_CONTENTS *elt;
  1069.   SHELL_VAR *old_var, *new_var;
  1070.   char *t;
  1071.  
  1072.   elt = remove_hash_item (name, hash_list);
  1073.  
  1074.   if (!elt)
  1075.     return (-1);
  1076.  
  1077.   old_var = (SHELL_VAR *)elt->data;
  1078.   new_var = old_var->prev_context;
  1079.  
  1080.   if (old_var && exported_p (old_var))
  1081.     array_needs_making++;
  1082.  
  1083.   if (new_var)
  1084.     {
  1085.       /* Has to be a variable, functions don't have previous contexts. */
  1086.       BUCKET_CONTENTS *new_elt;
  1087.  
  1088.       new_elt = add_hash_item (savestring (new_var->name), hash_list);
  1089.       new_elt->data = (char *)new_var;
  1090.  
  1091.       if (exported_p (new_var))
  1092.     set_var_auto_export (new_var->name);
  1093.     }
  1094.  
  1095.   /* Have to save a copy of name here, because it might refer to
  1096.      old_var->name.  If so, stupidly_hack_special_variables will
  1097.      reference freed memory. */
  1098.   t = savestring (name);
  1099.  
  1100.   free (elt->key);
  1101.   free (elt);
  1102.  
  1103.   dispose_variable (old_var);
  1104.   stupidly_hack_special_variables (t);
  1105.   free (t);
  1106.   return (0);
  1107. }
  1108.  
  1109. /* Remove the variable with NAME if it is a local variable in the
  1110.    current context. */
  1111. kill_local_variable (name)
  1112.      char *name;
  1113. {
  1114.   SHELL_VAR *temp = find_variable (name);
  1115.  
  1116.   if (temp && (temp->context == variable_context))
  1117.     {
  1118.       makunbound (name, shell_variables);
  1119.       return (0);
  1120.     }
  1121.   return (-1);
  1122. }
  1123.  
  1124. /* Get rid of all of the variables in the current context. */
  1125. int
  1126. variable_in_context (var)
  1127.      SHELL_VAR *var;
  1128. {
  1129.   return (var && var->context == variable_context);
  1130. }
  1131.  
  1132. void
  1133. kill_all_local_variables ()
  1134. {
  1135.   register int i, pass;
  1136.   register SHELL_VAR *var, **list;
  1137.   HASH_TABLE *varlist;
  1138.  
  1139.   /* XXX */
  1140.   if (!have_local_variables || have_local_variables[variable_context] == 0)
  1141.     return;
  1142.  
  1143.   for (pass = 0; pass < 2; pass++)
  1144.     {
  1145.       varlist = pass ? shell_functions : shell_variables;
  1146.  
  1147.       list = map_over (variable_in_context, varlist);
  1148.  
  1149.       if (list)
  1150.     {
  1151.       for (i = 0; var = list[i]; i++)
  1152.         makunbound (var->name, varlist);
  1153.  
  1154.       free (list);
  1155.     }
  1156.     }
  1157.  
  1158.   have_local_variables[variable_context] = 0;        /* XXX */
  1159. }
  1160.  
  1161. /* Delete the entire contents of the hash table. */
  1162. void
  1163. delete_all_variables (hashed_vars)
  1164.      HASH_TABLE *hashed_vars;
  1165. {
  1166.   register int i;
  1167.   register BUCKET_CONTENTS *bucket;
  1168.  
  1169.   for (i = 0; i < hashed_vars->nbuckets; i++)
  1170.     {
  1171.       bucket = hashed_vars->bucket_array[i];
  1172.  
  1173.       while (bucket)
  1174.     {
  1175.       BUCKET_CONTENTS *temp = bucket;
  1176.       SHELL_VAR *var, *prev;
  1177.  
  1178.       bucket = bucket->next;
  1179.  
  1180.       var = (SHELL_VAR *)temp->data;
  1181.  
  1182.       while (var)
  1183.         {
  1184.           prev = var->prev_context;
  1185.           dispose_variable (var);
  1186.  
  1187.           var = prev;
  1188.         }
  1189.  
  1190.       free (temp->key);
  1191.       free (temp);
  1192.     }
  1193.       hashed_vars->bucket_array[i] = (BUCKET_CONTENTS *)NULL;
  1194.     }
  1195. }
  1196.  
  1197. static SHELL_VAR *
  1198. new_shell_variable (name)
  1199.      char *name;
  1200. {
  1201.   SHELL_VAR *var;
  1202.  
  1203.   var = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
  1204.  
  1205.   bzero ((char *)var, sizeof (SHELL_VAR));
  1206.   var->name = savestring (name);
  1207.   return (var);
  1208. }
  1209.  
  1210. /* Do a function binding to a variable.  You pass the name and
  1211.    the command to bind to.  This conses the name and command. */
  1212. SHELL_VAR *
  1213. bind_function (name, value)
  1214.      char *name;
  1215.      COMMAND *value;
  1216. {
  1217.   SHELL_VAR *entry = find_function (name);
  1218.  
  1219.   if (!entry)
  1220.     {
  1221.       BUCKET_CONTENTS *elt;
  1222.  
  1223.       elt = add_hash_item (savestring (name), shell_functions);
  1224.  
  1225.       elt->data = (char *)new_shell_variable (name);
  1226.       entry = (SHELL_VAR *)elt->data;
  1227.       entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
  1228.       entry->assign_func = (DYNAMIC_FUNC *)NULL;
  1229.  
  1230.       /* Functions are always made at the top level.  This allows a
  1231.      function to define another function (like autoload). */
  1232.       entry->context = 0;
  1233.     }
  1234.  
  1235.   if (entry->value)
  1236.     dispose_command ((COMMAND *)entry->value);
  1237.  
  1238.   if (value)    /* I don't think this can happen anymore */
  1239.     entry->value = (char *)copy_command (value);
  1240.   else
  1241.     entry->value = (char *)NULL;
  1242.  
  1243.   entry->attributes |= att_function;
  1244.  
  1245.   if (mark_modified_vars)
  1246.     entry->attributes |= att_exported;
  1247.  
  1248.   entry->attributes &= ~att_invisible;    /* Just to be sure */
  1249.  
  1250.   array_needs_making = 1;
  1251.  
  1252.   return (entry);
  1253. }
  1254.  
  1255. /* Copy VAR to a new data structure and return that structure. */
  1256. SHELL_VAR *
  1257. copy_variable (var)
  1258.      SHELL_VAR *var;
  1259. {
  1260.   SHELL_VAR *copy = (SHELL_VAR *)NULL;
  1261.  
  1262.   if (var)
  1263.     {
  1264.       copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
  1265.  
  1266.       copy->attributes = var->attributes;
  1267.       copy->name = savestring (var->name);
  1268.  
  1269.       if (function_p (var))
  1270.     copy->value = (char *)copy_command ((COMMAND *)var->value);
  1271.       else if (var->value)
  1272.     copy->value = savestring (var->value);
  1273.       else
  1274.     copy->value = (char *)NULL;
  1275.  
  1276.       copy->dynamic_value = var->dynamic_value;
  1277.       copy->assign_func = var->assign_func;
  1278.  
  1279.       copy->context = var->context;
  1280.  
  1281.       /* Don't bother copying previous contexts along with this variable. */
  1282.       copy->prev_context = (SHELL_VAR *)NULL;
  1283.     }
  1284.   return (copy);
  1285. }
  1286.  
  1287. /* Make the variable associated with NAME be read-only.
  1288.    If NAME does not exist yet, create it. */
  1289. void
  1290. set_var_read_only (name)
  1291.      char *name;
  1292. {
  1293.   SHELL_VAR *entry = find_variable (name);
  1294.  
  1295.   if (!entry)
  1296.     {
  1297.       entry = bind_variable (name, "");
  1298.       if (!no_invisible_vars)
  1299.     entry->attributes |= att_invisible;
  1300.     }
  1301.   entry->attributes |= att_readonly;
  1302. }
  1303.  
  1304. /* Make the function associated with NAME be read-only.
  1305.    If NAME does not exist, we just punt, like auto_export code below. */
  1306. void
  1307. set_func_read_only (name)
  1308.      char *name;
  1309. {
  1310.   SHELL_VAR *entry = find_function (name);
  1311.  
  1312.   if (entry)
  1313.     entry->attributes |= att_readonly;
  1314. }
  1315.  
  1316. /* Make the variable associated with NAME be auto-exported.
  1317.    If NAME does not exist yet, create it. */
  1318. void
  1319. set_var_auto_export (name)
  1320.      char *name;
  1321. {
  1322.   SHELL_VAR *entry = find_variable (name);
  1323.  
  1324.   if (!entry)
  1325.     {
  1326.       entry = bind_variable (name, "");
  1327.       if (!no_invisible_vars)
  1328.     entry->attributes |= att_invisible;
  1329.     }
  1330.  
  1331.   set_auto_export (entry);
  1332. }
  1333.  
  1334. /* Make the function associated with NAME be auto-exported. */
  1335. void
  1336. set_func_auto_export (name)
  1337.      char *name;
  1338. {
  1339.   SHELL_VAR *entry = find_function (name);
  1340.  
  1341.   if (entry)
  1342.     {
  1343.       entry->attributes |= att_exported;
  1344.       array_needs_making = 1;
  1345.     }
  1346. }
  1347.  
  1348. /* Returns non-zero if STRING is an assignment statement.  The returned value
  1349.    is the index of the `=' sign. */
  1350. assignment (string)
  1351.      char *string;
  1352. {
  1353.   register int c, indx = 0;
  1354.  
  1355.   c = string[indx];
  1356.  
  1357.   if (!isletter (c) && c != '_')
  1358.     return (0);
  1359.  
  1360.   while (c = string[indx])
  1361.     {
  1362.       /* The following is safe.  Note that '=' at the start of a word
  1363.      is not an assignment statement. */
  1364.       if (c == '=')
  1365.     return (indx);
  1366.  
  1367.       if (!isletter (c) && !digit (c) && c != '_')
  1368.     return (0);
  1369.  
  1370.       indx++;
  1371.     }
  1372.   return (0);
  1373. }
  1374.  
  1375. static int
  1376. visible_var (var)
  1377.      SHELL_VAR *var;
  1378. {
  1379.   return (!invisible_p (var));
  1380. }
  1381.  
  1382. SHELL_VAR **
  1383. all_visible_variables ()
  1384. {
  1385.   SHELL_VAR **list;
  1386.  
  1387.   list = map_over (visible_var, shell_variables);
  1388.  
  1389.   if (list)
  1390.     sort_variables (list);
  1391.  
  1392.   return (list);
  1393. }
  1394.  
  1395. SHELL_VAR **
  1396. all_visible_functions ()
  1397. {
  1398.   SHELL_VAR **list;
  1399.  
  1400.   list = map_over (visible_var, shell_functions);
  1401.  
  1402.   if (list)
  1403.     sort_variables (list);
  1404.  
  1405.   return (list);
  1406. }
  1407.  
  1408. /* Return non-zero if the variable VAR is visible and exported. */
  1409. static int
  1410. visible_and_exported (var)
  1411.      SHELL_VAR *var;
  1412. {
  1413.   return (!invisible_p (var) && exported_p (var));
  1414. }
  1415.  
  1416. /* Make an array of assignment statements from the hash table
  1417.    HASHED_VARS which contains SHELL_VARs.  Only visible, exported
  1418.    variables are eligible. */
  1419. char **
  1420. make_var_array (hashed_vars)
  1421.      HASH_TABLE *hashed_vars;
  1422. {
  1423.   register int i, list_index;
  1424.   register SHELL_VAR *var;
  1425.   char **list = (char **)NULL;
  1426.   SHELL_VAR **vars;
  1427.  
  1428.   vars = map_over (visible_and_exported, hashed_vars);
  1429.  
  1430.   if (!vars)
  1431.     return (char **)NULL;
  1432.  
  1433.   list = (char **)xmalloc ((1 + array_len ((char **)vars)) * sizeof (char *));
  1434.  
  1435.   for (i = 0, list_index = 0; var = vars[i]; i++)
  1436.     {
  1437.       char *value;
  1438.  
  1439.       if (function_p (var))
  1440.     value = named_function_string
  1441.       ((char *)NULL, (COMMAND *)function_cell (var), 0);
  1442.       else
  1443.     value = value_cell (var);
  1444.  
  1445.       if (value)
  1446.     {
  1447.       int name_len = strlen (var->name);
  1448.       int value_len = strlen (value);
  1449.       char    *p;
  1450.  
  1451.       p = list[list_index] = xmalloc (2 + name_len + value_len);
  1452.       strcpy (p, var->name);
  1453.       p[name_len] = '=';
  1454.       strcpy (p + name_len + 1, value);
  1455.       list_index++;
  1456.     }
  1457.     }
  1458.  
  1459.   free (vars);
  1460.   list[list_index] = (char *)NULL;
  1461.   return (list);
  1462. }
  1463.  
  1464. /* Add STRING to the array of foo=bar strings that we already
  1465.    have to add to the environment.  */
  1466. assign_in_env (string)
  1467.      char *string;
  1468. {
  1469.   int size;
  1470.  
  1471.   int offset = assignment (string);
  1472.   char *name = savestring (string);
  1473.   char *temp, *value = (char *)NULL;
  1474.   int nlen, vlen;
  1475.  
  1476.   if (name[offset] == '=')
  1477.     {
  1478.       WORD_LIST *list;
  1479.  
  1480.       name[offset] = 0;
  1481.       temp = name + offset + 1;
  1482.       temp = tilde_expand (temp);
  1483.  
  1484.       list = expand_string_unsplit (temp, 0);
  1485.       value = string_list (list);
  1486.  
  1487.       if (list)
  1488.     dispose_words (list);
  1489.  
  1490.       free (temp);
  1491.     }
  1492.  
  1493.   if (!value)
  1494.     value = savestring ("");
  1495.  
  1496.   nlen = strlen (name);
  1497.   vlen = strlen (value);
  1498.   temp = xmalloc (2 + nlen + vlen);
  1499.   strcpy (temp, name);
  1500.   temp[nlen] = '=';
  1501.   strcpy (temp + nlen + 1, value);
  1502.   free (name);
  1503.   free (value);
  1504.  
  1505.   if (!temporary_env)
  1506.     {
  1507.       temporary_env = (char **)xmalloc (sizeof (char *));
  1508.       temporary_env [0] = (char *)NULL;
  1509.     }
  1510.  
  1511.   size = array_len (temporary_env);
  1512.   temporary_env = (char **)
  1513.     xrealloc (temporary_env, (size + 2) * (sizeof (char *)));
  1514.  
  1515.   temporary_env[size] = (temp);
  1516.   temporary_env[size + 1] = (char *)NULL;
  1517.   array_needs_making = 1;
  1518.  
  1519.   if (echo_command_at_execute)
  1520.     {
  1521.       /* The K*rn shell prints the `+ ' in front of assignment statements,
  1522.      so we do too. */
  1523.       fprintf (stderr, "%s%s\n", indirection_level_string (), temp);
  1524.       fflush (stderr);
  1525.     }
  1526.  
  1527.   return 1;
  1528. }
  1529.  
  1530. /* Search for NAME in ARRAY, an array of strings in the same format as the
  1531.    environment array (i.e, name=value).  If NAME is present, make a new
  1532.    variable and return it.  Otherwise, return NULL. */
  1533. static SHELL_VAR *
  1534. find_name_in_env_array (name, array)
  1535.      char *name;
  1536.      char **array;
  1537. {
  1538.   register int i, l = strlen (name);
  1539.  
  1540.   if (!array)
  1541.     return ((SHELL_VAR *)NULL);
  1542.  
  1543.   for (i = 0; array[i]; i++)
  1544.     {
  1545.       if (STREQN (array[i], name, l) && array[i][l] == '=')
  1546.     {
  1547.       SHELL_VAR *temp;
  1548.  
  1549.       temp = new_shell_variable (name);
  1550.  
  1551.       if (array[i][l + 1])
  1552.         temp->value = savestring (&array[i][l + 1]);
  1553.       else
  1554.         temp->value = (char *) NULL;
  1555.  
  1556.       temp->attributes = att_exported;
  1557.       temp->context = 0;
  1558.       temp->prev_context = (SHELL_VAR *)NULL;
  1559.  
  1560.       temp->dynamic_value = (DYNAMIC_FUNC *)NULL;
  1561.       temp->assign_func = (DYNAMIC_FUNC *)NULL;
  1562.  
  1563.       return (temp);
  1564.     }
  1565.     }
  1566.   return ((SHELL_VAR *)NULL);
  1567. }
  1568.  
  1569. /* Find a variable in the temporary environment that is named NAME.
  1570.    The temporary environment can be either the environment provided
  1571.    to a simple command, or the environment provided to a shell function.
  1572.    We only search the function environment if we are currently executing
  1573.    a shell function body (variable_context > 0).  Return a consed variable,
  1574.    or NULL if not found. */
  1575. SHELL_VAR *
  1576. find_tempenv_variable (name)
  1577.      char *name;
  1578. {
  1579.   SHELL_VAR *var = (SHELL_VAR *)NULL;
  1580.  
  1581.   if (temporary_env)
  1582.     var = find_name_in_env_array (name, temporary_env);
  1583.  
  1584.   /* We don't check this_shell_builtin because the command that needs the
  1585.      value from builtin_env may be a disk command run inside a script run
  1586.      with `.' and a temporary env. */
  1587.   if (!var && builtin_env)
  1588.     var = find_name_in_env_array (name, builtin_env);
  1589.  
  1590.   if (!var && variable_context && function_env)
  1591.     var = find_name_in_env_array (name, function_env);
  1592.  
  1593.   return (var);
  1594. }
  1595.  
  1596. /* Free the storage allocated to the string array pointed to by ARRAYP, and
  1597.    make that variable have a null pointer as a value. */
  1598. static void
  1599. dispose_temporary_vars (arrayp)
  1600.      char ***arrayp;
  1601. {
  1602.   if (!*arrayp)
  1603.     return;
  1604.  
  1605.   free_array (*arrayp);
  1606.   *arrayp = (char **)NULL;
  1607.   array_needs_making = 1;
  1608. }
  1609.  
  1610. /* Free the storage used in the variable array for temporary
  1611.    environment variables. */
  1612. void
  1613. dispose_used_env_vars ()
  1614. {
  1615.   dispose_temporary_vars (&temporary_env);
  1616. }
  1617.  
  1618. /* Free the storage used for temporary environment variables given to
  1619.    commands when executing inside of a function body. */
  1620. void
  1621. dispose_function_env ()
  1622. {
  1623.   dispose_temporary_vars (&function_env);
  1624. }
  1625.  
  1626. /* Free the storage used for temporary environment variables given to
  1627.    commands when executing a builtin command such as "source". */
  1628. void
  1629. dispose_builtin_env ()
  1630. {
  1631.   dispose_temporary_vars (&builtin_env);
  1632. }
  1633.  
  1634. /* Sort ARRAY, a null terminated array of pointers to strings. */
  1635. void
  1636. sort_char_array (array)
  1637.      char **array;
  1638. {
  1639.   qsort (array, array_len (array), sizeof (char *),
  1640.      (Function *)qsort_string_compare);
  1641. }
  1642.  
  1643. #define ISFUNC(s, o) ((s[o + 1] == '(')  && (s[o + 2] == ')'))
  1644.  
  1645. /* Add ASSIGN to ARRAY, or supercede a previous assignment in the
  1646.    array with the same left-hand side.  Return the new array. */
  1647. char **
  1648. add_or_supercede (assign, array)
  1649.      char *assign;
  1650.      register char **array;
  1651. {
  1652.   register int i;
  1653.   int equal_offset = assignment (assign);
  1654.  
  1655.   if (!equal_offset)
  1656.     return (array);
  1657.  
  1658.   /* If this is a function, then only supercede the function definition.
  1659.      We do this by including the `=(' in the comparison.  */
  1660.   if (assign[equal_offset + 1] == '(')
  1661.     equal_offset++;
  1662.  
  1663.   for (i = 0; array && array[i]; i++)
  1664.     {
  1665.       if (STREQN (assign, array[i], equal_offset + 1))
  1666.     {
  1667.       free (array[i]);
  1668.       array[i] = savestring (assign);
  1669.       return (array);
  1670.     }
  1671.     }
  1672.   array = (char **)xrealloc (array, ((2 + i) * sizeof (char *)));
  1673.   array[i++] = savestring (assign);
  1674.   array[i] = (char *)NULL;
  1675.   return (array);
  1676. }
  1677.  
  1678. /* Make the environment array for the command about to be executed.  If the
  1679.    array needs making.  Otherwise, do nothing.  If a shell action could
  1680.    change the array that commands receive for their environment, then the
  1681.    code should `array_needs_making++'. */
  1682. void
  1683. maybe_make_export_env ()
  1684. {
  1685.   register int i;
  1686.   register char **temp_array;
  1687.  
  1688.   if (array_needs_making)
  1689.     {
  1690.       if (export_env)
  1691.     free_array (export_env);
  1692.  
  1693. #ifdef SHADOWED_ENV
  1694.       export_env =
  1695.     (char **)xmalloc ((1 + array_len (shell_environment)) * sizeof (char *));
  1696.  
  1697.       for (i = 0; shell_environment[i]; i++)
  1698.     export_env[i] = savestring (shell_environment[i]);
  1699.       export_env[i] = (char *)NULL;
  1700.  
  1701. #else /* !SHADOWED_ENV */
  1702.  
  1703.       export_env = (char **)xmalloc (sizeof (char *));
  1704.       export_env[0] = (char *)NULL;
  1705.  
  1706. #endif /* SHADOWED_ENV */
  1707.  
  1708.       temp_array = make_var_array (shell_variables);
  1709.       for (i = 0; temp_array && temp_array[i]; i++)
  1710.     export_env = add_or_supercede (temp_array[i], export_env);
  1711.       free_array (temp_array);
  1712.  
  1713.       temp_array = make_var_array (shell_functions);
  1714.       for (i = 0; temp_array && temp_array[i]; i++)
  1715.     export_env = add_or_supercede (temp_array[i], export_env);
  1716.       free_array (temp_array);
  1717.  
  1718.       if (function_env)
  1719.     for (i = 0; function_env[i]; i++)
  1720.       export_env = add_or_supercede (function_env[i], export_env);
  1721.  
  1722.       if (temporary_env)
  1723.     for (i = 0; temporary_env[i]; i++)
  1724.       export_env = add_or_supercede (temporary_env[i], export_env);
  1725.  
  1726.       /* If we changed the array, then sort it alphabetically. */
  1727.       if (temporary_env || function_env)
  1728.     sort_char_array (export_env);
  1729.  
  1730.       array_needs_making = 0;
  1731.     }
  1732. }
  1733.  
  1734. /* We always put _ in the environment as the name of this command. */
  1735. void
  1736. put_command_name_into_env (command_name)
  1737.      char *command_name;
  1738. {
  1739.   char *dummy;
  1740.  
  1741.   dummy = xmalloc (4 + strlen (command_name));
  1742.  
  1743.   /* These three statements replace a call to sprintf */
  1744.   dummy[0] = '_';
  1745.   dummy[1] = '=';
  1746.   strcpy (dummy + 2, command_name);
  1747.   export_env = add_or_supercede (dummy, export_env);
  1748.   free (dummy);
  1749. }
  1750.  
  1751. /* We supply our own version of getenv () because we want library
  1752.    routines to get the changed values of exported variables. */
  1753.  
  1754. /* The NeXT C library has getenv () defined and used in the same file.
  1755.    This screws our scheme.  However, Bash will run on the NeXT using
  1756.    the C library getenv (), since right now the only environment variable
  1757.    that we care about is HOME, and that is already defined.  */
  1758. #if !defined (NeXT) && !defined (HPOSF1)
  1759. static char *last_tempenv_value = (char *)NULL;
  1760. extern char **environ;
  1761.  
  1762. char *
  1763. getenv (name)
  1764. #if defined (Linux) || defined (__bsdi__) || defined (convex)
  1765.      const char *name;
  1766. #else
  1767.      char const *name;
  1768. #endif /* !Linux */
  1769. {
  1770.   SHELL_VAR *var = find_tempenv_variable ((char *)name);
  1771.  
  1772.   if (var)
  1773.     {
  1774.       FREE (last_tempenv_value);
  1775.  
  1776.       last_tempenv_value = savestring (value_cell (var));
  1777.       dispose_variable (var);
  1778.       return (last_tempenv_value);
  1779.     }
  1780.   else if (shell_variables)
  1781.     {
  1782.       var = find_variable ((char *)name);
  1783.       if (var && exported_p (var))
  1784.     return (value_cell (var));
  1785.     }
  1786.   else
  1787.     {
  1788.       register int i, len = strlen (name);
  1789.  
  1790.       /* In some cases, s5r3 invokes getenv() before main(); BSD systems
  1791.          using gprof also exhibit this behavior.  This means that
  1792.          shell_variables will be 0 when this is invoked.  We look up the
  1793.      variable in the real environment in that case. */
  1794.  
  1795.       for (i = 0; environ[i]; i++)
  1796.     {
  1797.       if ((STREQN (environ[i], name, len)) && (environ[i][len] == '='))
  1798.         return (environ[i] + len + 1);
  1799.     }
  1800.     }
  1801.  
  1802.   return ((char *)NULL);
  1803. }
  1804. #endif /* !NeXT && !HPOSF1 */
  1805.